package com.pi.dc.service;

import java.util.List;

import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;

import org.apache.commons.lang3.StringUtils;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.NotBlank;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import com.alibaba.fastjson.JSON;
import com.pi.base.dto.result.respcode.smart.DcResp;
import com.pi.base.enumerate.record.RecordState;
import com.pi.base.exception.ServiceException;
import com.pi.base.util.bean.BeanUtil;
import com.pi.base.util.bean.ObjectTool;
import com.pi.dc.dao.entity.DcDeviceInfoEntity;
import com.pi.dc.dao.mapper.DcDeviceInfoMapper;
import com.pi.dc.dao.param.DcDeviceInfoParam;
import com.pi.uc.dao.entity.UcUserShareEntity;
import com.pi.uc.service.UcUserShareService;

/**
 * @descriotion 添加设备基础信息(一般这个操作都是基于业务， 所以，直接采用dao的entity)
 * @author chenmf
 * @date 2019年05月02日11:44:46
 */
@Service
public class DcDeviceInfoService {
  
  private static final Logger logger = LoggerFactory.getLogger(DcDeviceInfoService.class);
  
  @Autowired
  private DcDeviceInfoMapper deviceInfoMapper;
  
  @Autowired
  private UcUserShareService userShareService;
  
  public void add(DcDeviceInfoEntity entity) {
    logger.info("设备基础信息添加: {}", JSON.toJSONString(entity));
    checkAddDeviceInfo(entity);
    wrapAddParam(entity);
    deviceInfoMapper.insert(entity);
  }
  
  public void addIfNecessary(DcDeviceInfoEntity entity) {
    logger.info("添加或覆盖设备基础信息: {}", JSON.toJSONString(entity));
    checkAddDeviceInfo(entity);
    wrapAddParam(entity);
    DcDeviceInfoEntity devInfo = getByDevCodeIfExist(entity.getDevCode(), entity.getDevType());
    if(null == devInfo) {
      deviceInfoMapper.insert(entity);
    }else {
      BeanUtil.beanUpdate(devInfo, entity);
      deviceInfoMapper.updateById(devInfo);
    }
    entity = devInfo;
  }
  
  public void updateBaseDevInfo(DcDeviceInfoEntity exist) {
    checkBaseDevInfoUpdate(exist);
    deviceInfoMapper.updateById(exist);
  }

  public DcDeviceInfoEntity getByDevCodeIfExist(
      @NotBlank(message= "DC_DEV.DEV_CODE_EMPTY")
      String devCode, 
      @NotNull(message = "DC_DEV.DEV_TYPE_EMPTY")
      Integer devType) {
    DcDeviceInfoParam param = new DcDeviceInfoParam();
    param.setDevCode(devCode);
    param.setDevType(devType);
    return ObjectTool.getOne(deviceInfoMapper.findList(param));
  }
  
  public DcDeviceInfoEntity getByDevCodeIfExist(
      @NotBlank(message= "DC_DEV.DEV_CODE_EMPTY")
      String devCode) {
    DcDeviceInfoParam param = new DcDeviceInfoParam();
    param.setDevCode(devCode);
    return ObjectTool.getOne(deviceInfoMapper.findList(param));
  }
  
  
  public DcDeviceInfoEntity getByDevCode(
      @NotBlank(message= "DC_DEV.DEV_CODE_EMPTY")
      String devCode, 
      @NotNull(message = "DC_DEV.DEV_TYPE_EMPTY")
      Integer devType) {
    DcDeviceInfoParam param = new DcDeviceInfoParam();
    param.setDevCode(devCode);
    param.setDevType(devType);
    List<DcDeviceInfoEntity> list = deviceInfoMapper.findList(param);
    if(CollectionUtils.isEmpty(list)) {
      throw new ServiceException("DC_DEV.DEV_INFO_EMPTY");
    }
    return ObjectTool.getOne(list);
  }
  
  public DcDeviceInfoEntity getByIdIfExist(
      @NotNull(message="DC_DEV.DEV_ID_EMPTY")
      @Min(value = 1, message="DC_DEV.DEV_ID_EMPTY")
      Long devId
      ) {
    return deviceInfoMapper.findOne(devId);
  }
  
  /**
   * @description 根据用户和被子编号查询可能的被子列表
   * @param ownerId
   * @param bedId 可选，被子编号
   * @return
   */
  public List<DcDeviceInfoEntity> queryUserDevInfo(Long ownerId, Long devId){
    DcDeviceInfoParam param = new DcDeviceInfoParam();
    param.setOwnerId(ownerId);
    param.setState(RecordState.STATE_NORMAL.getCode());
    param.setId(devId);
    return deviceInfoMapper.findList(param);
  }
  
  /**
   * @description 根据用户和被子编号查询可能的被子列表
   * @param ownerId
   * @param bedId 可选，被子编号
   * @return
   */
  public List<DcDeviceInfoEntity> queryUserDevInfo(Long ownerId){
    DcDeviceInfoParam param = new DcDeviceInfoParam();
    param.setOwnerId(ownerId);
    param.setState(RecordState.STATE_NORMAL.getCode());
    return deviceInfoMapper.findList(param);
  }
  
  public DcDeviceInfoEntity getById(
      @NotNull(message="DC_DEV.DEV_ID_EMPTY")
      @Min(value = 1, message="DC_DEV.DEV_ID_EMPTY")
      Long devId
      ) {
    DcDeviceInfoEntity entity = deviceInfoMapper.findOne(devId);
    if(null == entity){
      throw new ServiceException("DC_DEV.DEV_INFO_EMPTY");
    }
    return entity;
  }
  
  public void updateDeviceName(
      @NotNull(message="DC_DEVICE.DEVICE_USER_NOT_FOUND") Long loginUserId, 
      @NotNull(message="DC_DEVICE.DEVICE_ID_EMPTY")Long devId, 
      @NotBlank(message="DC_DEVICE.DEVICE_NAME_EMPTY")
      @Length(min = 1, max = 40, message="DC_DEVICE.DEVICE_LENGTH_ILLGA")
      String deviceName){
    //检查用户是否有此设备权限
    DcDeviceInfoEntity entity = getById(devId);
    if(null == entity || entity.getState() != RecordState.STATE_NORMAL.getCode()){
      throw new ServiceException("DC_DEV.DEV_INFO_EMPTY");
    }
    if(entity.getOwnerId() != loginUserId.longValue()){
      throw new ServiceException(DcResp.RESP_PRIVILEGE_NOT_FOUND);
    }
    entity.setDevName(deviceName);
    deviceInfoMapper.updateById(entity);
  }
  
  public Long countAllDevice(){
    return deviceInfoMapper.count();
  }
  
  public List<DcDeviceInfoEntity> queryUserBedListByShare(
      @NotNull(message="DC_DEVICE.DEVICE_USER_NOT_FOUND") Long userId,
      Long shareId){
    Long ownerId = queryUserByShare(userId, shareId);
    return queryUserDevInfo(ownerId);
  }
  
  /**
   * @description 根据分享和被子的编号，查询当前用户有权限的被子列表
   * @param userId
   * @param shareId
   * @param bedId
   * @return
   */
  public List<DcDeviceInfoEntity> validAndQueryDevInfo(
      @NotNull(message="DC_DEVICE.DEVICE_USER_NOT_FOUND") Long loginUserId,
      Long shareId, Long bedId){
    if(null == shareId && null == bedId) {
      throw new ServiceException("UC_SHARE.SHARE_INFO_AND_DEVID_EMPTY");
    }
    
    Long ownerId = queryUserByShare(loginUserId, shareId);
    List<DcDeviceInfoEntity> bedList = queryUserDevInfo(ownerId, bedId);
    return bedList;
  }
  
  private Long queryUserByShare(Long loginUserId, Long shareId) {
    Long ownerId;
    if(null != shareId){
      //分享路径判断
      UcUserShareEntity shareRelation = 
          userShareService.getShareRelation(shareId, loginUserId);
      ownerId = shareRelation.getShareUserId();
    }else{
      ownerId = loginUserId;
    }
    return ownerId;
  }
  
  private void checkAddDeviceInfo(DcDeviceInfoEntity entity) {
    if(null == entity) {
      throw new ServiceException("DC_DEV.DEV_INFO_EMPTY");
    }   
    if(null == entity.getDevName()) {
      throw new ServiceException("DC_DEV.DEV_NAME_EMPTY");
    }
    if(null == entity.getDevType()) {
      throw new ServiceException("DC_DEV.DEV_TYPE_EMPTY");
    }
    if(null == entity.getSourceId()) {
      throw new ServiceException("REQ_COMMON.SOURCE_ID_EMPTY");
    }
  }
  
  private void checkBaseDevInfoUpdate(DcDeviceInfoEntity entity) {
    if(null == entity) {
      throw new ServiceException("DC_DEV.DEV_INFO_EMPTY");
    }   
    if(null == entity.getId()) {
      throw new ServiceException("DC_DEV.DEV_ID_EMPTY");
    }
  }
  
  private void wrapAddParam(DcDeviceInfoEntity entity) {
    if(null == entity.getDevModel()) {
      entity.setDevModel(StringUtils.EMPTY);
    }
    if(null == entity.getFirmwareVersion()) {
      entity.setFirmwareVersion(StringUtils.EMPTY);
    }
    if(null == entity.getSoftwareVersion()) {
      entity.setSoftwareVersion(StringUtils.EMPTY);
    }
    entity.setState(RecordState.STATE_NORMAL.getCode());
  }

  public void delDeviceInfo(Long devId, Long operateUserId) {
    DcDeviceInfoEntity entity = getById(devId);
    entity.setState(RecordState.STATE_DELETE.getCode());
    deviceInfoMapper.updateById(entity);
  }
}
